package model;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import view.MainF;

public class Section {
	 MainF mainF;
	private ModelClass modelClass;
	private String name;
	private int id;
	private int houseId;
	private Plant plant;
	private boolean notification;
	private boolean alarm;
	private boolean empty;
	private JButton tile;
	private int tilePicture;

	public Section(ModelClass modelClass, int id, int houseId, String name) {
		this.mainF = mainF;
		this.modelClass = modelClass;
		this.id = id;
		this.houseId = houseId;
		this.name = name;
		this.alarm = alarm;
		this.empty = empty;
		tilePicture = 1;
	}

	//Checks alarm, empty and plant finished-notification.
	public void checkAlarmEmptyNotiFication(int houseTemp, int houseLight,
			int houseCO2, int houseHumidity) {
		alarm = false;
		empty = false;
		notification = false;
		if (plant != null) {
			//sets plant-finished notification if production-state > 95 
			if (plant.getProdState() > 95) {
				notification = true;
			}
			//Checks the house climate with the plants optimal growing conditions. 
			//If the variance is too large alarm is set to true. 
			int prTemp = Math.abs((int) (((double) plant.getOptTemp()
					/ (double) houseTemp - 1) * 100));
			int prLight = Math.abs((int) (((double) plant.getOptLigt()
					/ (double) houseLight - 1) * 100));
			int prCO2 = Math.abs((int) (((double) plant.getOptCO2()
					/ (double) houseCO2 - 1) * 100));
			int prHumidity = Math.abs((int) (((double) plant.getOptFugt()
					/ (double) houseHumidity - 1) * 100));
			if (prTemp > 30 || prLight > 30 || prHumidity > 30) {
				alarm = true;
			}
		} else {
			empty = true;
		}
	}

	
	// Method that creates tile with specific layout
	public JButton getSectionTile() {
		tile = new JButton();
		tile.setBorder(null);
		tile.setBackground(new Color(34, 177, 76));
		BufferedImage img = modelClass.getVariables().getImgTile();
		BufferedImage imgPressed = modelClass.getVariables()
				.getImgTilePressed();
		SectionThread thread = new SectionThread(tile, modelClass);
		tile.setIcon(new ImageIcon(thread.process(img, 1)));
		tile.setPressedIcon(new ImageIcon(thread.process(imgPressed, 1)));

		return tile;
	}
	
	//Method that plants a plant into section and maybe stores it in the database depending on
	// the value of the boolean dBOrNot.
	public void setPlant(Plant plant, boolean dBOnOff) {
			if (plant != null) {
				this.plant = plant;
			} else {
				this.plant = plant;
			}

			if (dBOnOff) {
				modelClass.getDb().uploadAddedPlant(plant.getTypeID(), id);
			}

		}
	

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public int getHouseId() {
		return houseId;
	}

	public void setHouseId(int houseId) {
		this.houseId = houseId;
	}
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Plant getPlant() {
		return plant;
	}
	

	public Boolean getAlarm() {
		return alarm;
	}

	public void setAlarm(Boolean alarm) {
		this.alarm = alarm;
	}

	public Boolean getEmpty() {

		return empty;
	}

	public boolean isNotification() {
		return notification;
	}

	public void setNotification(boolean notification) {
		this.notification = notification;
	}

	public void setEmpty(Boolean empty) {
		this.empty = empty;
	}

	public int getTilePicture() {
		return tilePicture;
	}

	public void setTilePicture(int tilePicture) {
		this.tilePicture = tilePicture;
	}
	// Class that will is used to change the images of the tile
	// It's uses a thread that runs in interval changing the image
	class SectionThread extends Thread {
		String s = null;
		JButton tile;
		Boolean tileNr = true;
		Random r = new Random();
		ModelClass modelClass;
		Variables variables;
		// the constructure
		public SectionThread(JButton tile, ModelClass modelClass) {
			this.tile = tile;
			this.modelClass = modelClass;
			this.variables = modelClass.getVariables();
			start();
		}
		//thread that runs
		public void run() {
			while (true) {
				try {
					sleep(r.nextInt(15000) + 5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				BufferedImage img = null;
				img = variables.getImgTile();
				BufferedImage imgPressed = null;
				imgPressed = variables.getImgTilePressed();
				transitionImage(img);
				tile.setPressedIcon(new ImageIcon(process(imgPressed, 1)));
			}
		}
		// finds out what picture to change to
		public void transitionImage(BufferedImage img) {
			BufferedImage imgStart = null;
			BufferedImage imgEnd = null;
			// if(tilePicture==1){
			// imgStart = process(img,1);
			// imgEnd = process(img,2);
			// tilePicture = 2;
			// }else if(tilePicture ==2){
			// imgStart = process(img,2);
			// imgEnd = process(img,3);
			// tilePicture=3;
			//
			// }else if (tilePicture==3){
			//
			// imgStart = process(img,3);
			// imgEnd = process(img,1);
			// tilePicture=1;
			// }

			if (tilePicture == 1) {
				imgStart = process(img, 1);
				imgEnd = process(img, 2);
				tilePicture = 2;
			} else if (tilePicture == 2) {
				imgStart = process(img, 2);
				imgEnd = process(img, 1);
				tilePicture = 1;

			}

			double endPos = 100;
			// loop that will illustrate the grafik
			// makes the picture smootly come in from the side
			for (double i = 0; i < endPos; i++) {

				try {
					sleep(20);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				tile.setIcon(new ImageIcon(processTransistionImage(imgStart,
						imgEnd, i, endPos)));
			}
		}
		// that takes to images and merges them together
		public BufferedImage processTransistionImage(BufferedImage imgStart,
				BufferedImage imgEnd, double pos, double endPos) {
			int w = imgStart.getWidth();
			int h = imgStart.getHeight();
			BufferedImage img = new BufferedImage(w, h,
					BufferedImage.TYPE_INT_ARGB);
			Graphics2D g2d = img.createGraphics();
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
					RenderingHints.VALUE_ANTIALIAS_ON);
			double xpos = w / endPos;
			g2d.drawImage(imgStart, (int) (0 + xpos * pos), 0, null);
			g2d.drawImage(imgEnd, -w + (int) (0 + xpos * pos), 0, null);

			return img;
		}
		// method that takes an image and writes the corresponding data onto that image
		public BufferedImage process(BufferedImage old, int type) {
			int w = old.getWidth();
			int h = old.getHeight();
			BufferedImage img = new BufferedImage(w, h,
					BufferedImage.TYPE_INT_ARGB);
			Graphics2D g2d = img.createGraphics();
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
					RenderingHints.VALUE_ANTIALIAS_ON);
			g2d.drawImage(old, 0, 0, null);
			int y = 0;
			if (notification) {
				g2d.drawImage(variables.getImgNotification(), 165, 100, null);
				y += 35;
			}
			if (alarm) {
				g2d.drawImage(variables.getImgWarning(), 165, 100 - y, null);
				y += 35;
			}
			if (empty) {
				g2d.drawImage(variables.getImgEmptyIcon(), 165, 100 - y, null);
			}
			g2d.setPaint(Color.WHITE);
			Font font = variables.getFontTileHeader();
			font = font.deriveFont(30f);
			g2d.setFont(font);
			String s = name;
			g2d.drawString(s, 5, 25);

			if (type == 1) {

				font = font.deriveFont(15f);
				g2d.setFont(font);
				DecimalFormat df = new DecimalFormat("#.##");
				if (plant != null) {

					FontMetrics metrics = g2d.getFontMetrics(g2d.getFont());
					String name = plant.getName();
					int nameSize = metrics.stringWidth(name);

					String prod = "";
					if (plant.getPlantGrowthHisto().size() - 1 > 0) {
						prod = ""
								+ df.format(plant.getPlantGrowthHisto().get(
										plant.getPlantGrowthHisto().size() - 1));
					}
					int prodSize = metrics.stringWidth(prod);

					String curPS = "";
					if (plant.getPlantGrowthHisto().size() - 2 > 0) {
						curPS = ""
								+ df.format(plant.getPlantGrowthHisto().get(
										plant.getPlantGrowthHisto().size() - 2));
					}
					int curPhoSize = metrics.stringWidth("" + curPS);

					int prevPhotSize = 0;
					String prevPS = "";
					if (plant.getPlantGrowthHisto().size() - 4 > 0) {
						prevPS = ""
								+ df.format(plant.getPlantGrowthHisto().get(
										plant.getPlantGrowthHisto().size() - 4));
						prevPhotSize = metrics.stringWidth(prevPS);
					}

					g2d.drawString("Plant:", 5, 45);
					g2d.drawString(name, 150 - nameSize, 45);
					g2d.drawString("Prod State: ", 5, 60);
					g2d.drawString(prod, 150 - prodSize, 60);
					g2d.drawString("Cur phSynt :", 5, 75);
					g2d.drawString(curPS, 150 - curPhoSize, 75);
					g2d.drawString("Prev phSynt : ", 5, 90);
					g2d.drawString(prevPS, 150 - prevPhotSize, 90);

				}

			} else if (type == 2) {
				font = font.deriveFont(15f);
				g2d.setFont(font);

				if (plant != null) {
					ArrayList<Double> plantProd = plant.getPlantGrowthHisto();

					double[][] data = new double[plantProd.size() / 2][2];
					boolean trueFalse = false;
					int index = 0;
					for (Double value : plantProd) {
						if (trueFalse) {
							data[index][0] = value;
							trueFalse = false;
							index++;
						} else {
							data[index][1] = value;
							trueFalse = true;
						}

					}
					GraphAPI graph = new GraphAPI();
					graph = new GraphAPI();
					graph.getColors().add(0, new Color(255, 0, 0));
					graph.getNames().add(0, "Growth Progess");
					graph.getNames().add(1, "Fotosyntese");

					graph.paintDataGraph(g2d, data, 18, 40, 135, 80);
				}

			} else if (type == 3) {
				font = font.deriveFont(15f);
				g2d.setFont(font);
				g2d.drawString("Cur", 60, 50);
				g2d.drawString("Opt", 95, 50);
				g2d.drawString("Temp", 5, 60);
				g2d.drawString("Humd", 5, 75);
				g2d.drawString("Light", 5, 90);
				g2d.drawString("CO2", 5, 105);
			}

			g2d.dispose();
			return img;
		}
	}
}